import 'dart:io';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:kq_flutter_core_widget/utils/file_util.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:kq_flutter_core_widget/utils/str_util.dart';

import './kq_image.dart' as kq;
import '../../config/kq_core_global.dart';
import '../../resources/images.dart';
import '../../utils/native/oss_native_util.dart';

/// 图片状态
enum ImageStatus { downloading, error, done }

/// 阿里云OSS图片加载控件
///
/// 注意：debug模式用的[gofactory4test]bucket
class OssImage extends StatefulWidget {
  ///阿里云OSS key
  final String ossKey;

  /// 加载中的图片,如果传了[placeholderBuilder]则此值无效
  final String? placeHolder;

  /// 图片未加载之前显示内容构建器，不传则使用[placeHolder]
  final PlaceholderWidgetBuilder? placeholderBuilder;

  /// 错误的图片，不传则使用[placeHolder]
  final String? errorImage;

  /// 图片加载失败时显示的组件，仅对[ImageType.oss]、[ImageType.http]和[ImageType.file]有效，不传则使用[placeholderBuilder]
  final kq.ErrorWidgetBuilder? errorImageBuilder;

  /// 指定宽度，用于获取阿里云OSS图片的宽度
  final double width;

  /// 指定高度，用于获取阿里云OSS图片的高度
  final double height;

  /// 指定缩放类型
  final BoxFit? fit;

  /// 图片颜色
  final Color? color;

  /// 图片混合模式，结合[color] 使用
  final BlendMode? colorBlendMode;

  /// 包名，如果应用组件库内部图片，需要使用[KqCoreGlobal.packageName]
  final String? package;

  final String? tag;

  const OssImage(
      {Key? key,
      required this.ossKey,
      this.placeHolder,
      this.placeholderBuilder,
      this.errorImage,
      this.errorImageBuilder,
      this.color,
      this.colorBlendMode,
      required this.width,
        required this.height,
      this.package,
      this.tag,
      this.fit})
      : super(key: key);

  @override
  State<OssImage> createState() => _OssImageState();
}

class _OssImageState extends State<OssImage> {
  /// OSS下载文件路径
  String _filePath = '';

  /// 加载状态
  ImageStatus? _imgStatus;

  String? _tag;

  @override
  void initState() {
    _tag = widget.tag;
    _tag = _tag ?? StrUtil.uuid();
    _downloadFile();
    super.initState();
  }

  _downloadFile({bool needUpdate = true}) async {
    if (widget.ossKey.isEmpty) {
      if (mounted) {
        if (needUpdate) {
          setState(() {
            _filePath = '';
            _imgStatus = ImageStatus.error;
          });
        } else {
          _filePath = '';
          _imgStatus = ImageStatus.error;
        }
      }
      return;
    }
    var util = KqScreenUtil();
    var ossCacheFile = await OssNativeUtil.getOssCacheFile(
      ossKey: widget.ossKey,
      width: (widget.width * (util.pixelRatio ?? 1)),
      height:(widget.height * (util.pixelRatio ?? 1)),
    );
    if (ossCacheFile != null) {
      if (mounted) {
        setState(() {
          _filePath = ossCacheFile.filePath;
          _imgStatus = ImageStatus.done;
        });
      }
      return;
    }
    setState(() {
      _imgStatus = ImageStatus.downloading;
    });
    var ossResult = await OssNativeUtil.ossDownloadImage(
        ossKey: widget.ossKey,
        width: (widget.width * (util.pixelRatio ?? 1)),
        height:(widget.height * (util.pixelRatio ?? 1)),
        scaleType: widget.fit ?? BoxFit.none,
        tag: _tag);
    if (ossResult == null) {
      if (mounted) {
        setState(() {
          _filePath = '';
          _imgStatus = ImageStatus.error;
        });
      }
    } else {
      if (mounted) {
        setState(() {
          _filePath = ossResult.filePath;
          _imgStatus = ImageStatus.done;
        });
      }
    }
  }

  /// 取消下载
  _cancelDownload({String? customTag}) async {
    if (_tag == null && customTag == null) {
      return;
    }
    await OssNativeUtil.ossCancelDownload(tag: customTag ?? _tag ?? '');
  }

  @override
  Widget build(BuildContext context) {
    return _buildImage(context);
  }

  @override
  void didUpdateWidget(covariant OssImage oldWidget) {
    if (oldWidget.ossKey != widget.ossKey) {
      if (_tag != null) {
        _cancelDownload(customTag: _tag!);
      }
      _tag = widget.tag ?? StrUtil.uuid();
      _downloadFile(needUpdate: false);
    }
    super.didUpdateWidget(oldWidget);
  }

  Widget _buildImage(BuildContext context) {
    if (_imgStatus == ImageStatus.downloading) {
      if (widget.placeholderBuilder != null) {
        return widget.placeholderBuilder!.call(context, widget.ossKey);
      }

      return Image.asset(
        widget.placeHolder ?? Images.commonPicJinshuYuanjiao44,
        width: widget.width,
        height: widget.height,
        fit: widget.fit,
        errorBuilder: (context, error, stackTrace) {
          return _builderError(context, error);
        },
        package: widget.placeHolder != null
            ? widget.package
            : KqCoreGlobal.packageName,
      );
    } else if (_imgStatus == ImageStatus.error || _filePath.isEmpty) {
      if (widget.errorImageBuilder != null) {
        return widget.errorImageBuilder!.call(context, widget.ossKey, null);
      }
      if (widget.placeholderBuilder != null) {
        return widget.placeholderBuilder!.call(context, widget.ossKey);
      }
      return Image.asset(
        widget.errorImage ??
            widget.placeHolder ??
            Images.commonPicJinshuYuanjiao44,
        width: widget.width,
        height: widget.height,
        errorBuilder: (context, error, stackTrace) {
          return _builderError(context, error);
        },
        fit: widget.fit,
        package: (widget.errorImage != null || widget.placeHolder != null)
            ? widget.package
            : KqCoreGlobal.packageName,
      );
    } else {
      try {
        var file = File(_filePath);
        return Image.file(
          file,
          width: widget.width,
          height: widget.height,
          color: widget.color,
          colorBlendMode: widget.colorBlendMode,
          errorBuilder: (context, error, stackTrace) {
            file.delete();
            return _builderError(context, error);
          },
          fit: widget.fit,
        );
      } catch (e) {
        return _builderError(context, "");
      }
    }
  }

  /// 错误图片
  Widget _builderError(BuildContext context, dynamic error) {
    if (widget.errorImageBuilder != null) {
      return widget.errorImageBuilder!.call(context, widget.ossKey, error);
    }

    return Image.asset(
      widget.errorImage ?? Images.commonPicJinshuYuanjiao44,
      width: widget.width,
      height: widget.height,
      fit: widget.fit ?? BoxFit.cover,
      package:
          widget.errorImage != null ? widget.package : KqCoreGlobal.packageName,
    );
  }

  @override
  void dispose() {
    _cancelDownload();
    super.dispose();
  }
}
